package com.tool.grab.vpn.task;

import android.net.VpnService;

import com.tool.grab.vpn.header.IPPacket;
import com.tool.grab.vpn.tunnel.TunnelInterface;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.util.Iterator;

public class TunnelService implements Runnable{
    private VpnService service;
    private Selector selector;
    private ServerSocketChannel channel;
    private boolean isRun;


    public TunnelService (VpnService service) throws IOException{
        this.service = service;
        selector = Selector.open();
        channel = ServerSocketChannel.open();
        channel.socket().bind(new InetSocketAddress(0));
    }

    public void start(){
        Thread thread = new Thread(this,"TunnelService");
        thread.start();
    }

    public void receivePacket(byte[] bytes,int size){
        IPPacket ipPacket = new IPPacket(bytes,0,size);

        switch (ipPacket.getProtocl()){
            case IPPacket.PROTOCL_TCP:
                onCreateTCPTunnel(ipPacket);
                break;
            case IPPacket.PROTOCL_UDP:
                onCreateUDPTunnel(ipPacket);
                break;
        }
    }

    private void onCreateTCPTunnel(IPPacket packet){
        try {
            TCPTunnel tunnel = new TCPTunnel(selector);

        } catch (IOException e) {}
    }

    private void onCreateUDPTunnel(IPPacket packet){

    }




    @Override
    public void run() {
        isRun = true;
        try {
            while (isRun){
                int count = selector.select();

                if(count <= 0 ){
                   Thread.sleep(20);
                   continue;
                }

                Iterator<SelectionKey> keyIterator = selector.selectedKeys().iterator();

                while (keyIterator.hasNext()){

                    SelectionKey key = keyIterator.next();

                    if(key.isValid()){

                        Object object = key.attachment();

                       if(object != null && object instanceof TunnelEventListener){
                            ((TunnelEventListener) object).keyReady(key);
                        }
                    }

                    keyIterator.remove();
                }
            }
        }catch (Exception e){
            stop();
        }
    }

    public boolean isRun() {
        return isRun;
    }

    public void stop(){
        isRun = false;
        if(selector != null){
            try {
                selector.close();
            } catch (IOException e) {}finally {
                selector = null;
            }
        }
    }
}
